package dryven.codegen.asm;

import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

import dryven.codegen.asm.typeinfo.ClassTypeInfo;

public class ExceptionHandler {
	
	private Class<? extends Throwable> _exceptionType;
	private TryCatchBlock _block;
	private Label _handlerLabel;
	private boolean _isFinished = false;
	private TempValue _exception;
	
	public ExceptionHandler(Class<? extends Throwable> exceptionType,
			TryCatchBlock block) {
		super();
		_exceptionType = exceptionType;
		_block = block;
		_handlerLabel = new Label();
	}

	public void start(ExceptionScope scope) {
		start();
		scope.setException(getException());
		scope.setBuilder(_block.getBuilder());
		scope.addCode();
		finish();
	}
	
	public Class<? extends Throwable> getExceptionType() {
		return _exceptionType;
	}
	
	public void start() {
		MethodVisitor mv = _block.getBuilder().getMethodVisitor();
		mv.visitLabel(_handlerLabel);
		_exception = new TempValue(new ClassTypeInfo(_exceptionType), _block.getBuilder());
	}
	public void finish() {
		
		if(_block.isOnlyUnfinishedExceptionHandler(this)) {
			finishTryCatchBlock();
		}
		_isFinished = true;
	}
	
	private void finishTryCatchBlock() {
		MethodVisitor mv = _block.getBuilder().getMethodVisitor();
		mv.visitLabel(_block.getJumpOverHandlersLabel());
		//TODO: calculate frame delta
	}
	
	public TempValue getException() {
		return _exception;
	}

	public Label getHandlerLabel() {
		return _handlerLabel;
	}
	
	protected boolean isFinished() {
		return _isFinished;
	}
}
